package com.party.mem.biz.user;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.party.common.constant.Constant;
import com.party.common.constant.WechatConstant;
import com.party.common.redis.StringJedis;
import com.party.common.utils.CookieUtil;
import com.party.common.utils.wechat.WechatUtils;
import com.party.core.exception.BusinessException;
import com.party.core.model.member.ScanLoginOutput;
import com.party.core.model.member.ScanLoginStatus;
import com.party.core.model.member.XzgsAccountEnum;
import com.party.core.model.system.RoleEnum;
import com.party.core.model.system.SysConfig;
import com.party.core.service.system.ISysConfigService;
import com.party.core.service.system.ISysRoleService;
import com.party.mem.web.dto.AjaxResult;
import com.party.mem.web.security.CurrentUser;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.CookieHandler;
import java.net.CookieManager;
import java.net.CookiePolicy;
import java.net.HttpCookie;
import java.util.List;
import java.util.Map;

/**
 * @ClassName LoginBizService
 * @Description 登录业务处理
 * @Author yifeng
 * @Date 2019/1/30 10:18
 **/
@Service
public class LoginBizService {
    Logger logger = LoggerFactory.getLogger(getClass());

    @Value("#{party['scan_login_domain']}")
    private String scan_login_domain;

    @Autowired
    private StringJedis stringJedis;
    @Autowired
    private ISysConfigService sysConfigService;
    @Autowired
    private ISysRoleService sysRoleService;


    /**
     * @param token
     * @return void
     * @Author yifeng
     * @Description 删除图片
     * @Date 10:22 2019/1/30
     **/
    public void deleteCloudQrCode(String token) {
        if (StringUtils.isNotEmpty(token)) {
            stringJedis.delete(Constant.SCAN_LOGIN + token);

//            String filePath = fileBizService.getUploadCIPath("loginQrCode", Constant.ADMIN_ID);
//            String deletePath = CosBizService.getDeleteQrCodePath(filePath, token);
//            cosBizService.deleteFile(deletePath);
        }
    }

    /**
     * @param lgToken redis key 登录token
     * @return com.party.core.model.member.ScanLoginOutput
     * @Author yifeng
     * @Description 获取扫码登录redis数据
     * @Date 15:12 2019/2/19
     **/
    public ScanLoginOutput getLoginOutputRedis(String lgToken) {
        String value = stringJedis.getValue(Constant.SCAN_LOGIN + lgToken);
        if (com.party.common.utils.StringUtils.isNotEmpty(value)) {
            ScanLoginOutput loginOutput = JSONObject.parseObject(value, ScanLoginOutput.class);
            return loginOutput;
        }
        return null;
    }

    /**
     * @param loginOutput redis value
     * @return void
     * @Author yifeng
     * @Description 设置扫码登录redis数据
     * @Date 15:14 2019/2/19
     **/
    public void setLoginOutRedis(ScanLoginOutput loginOutput) {
        // redis设置有效期为1个小时
        stringJedis.setValue(Constant.SCAN_LOGIN + loginOutput.getLgToken(), JSONObject.toJSONString(loginOutput), 3600);
    }

    /**
     * @param loginOutput
     * @param request
     * @param response
     * @return void
     * @Author yifeng
     * @Description 登录
     * @Date 16:53 2019/2/19
     **/
    public String scanLogin(ScanLoginOutput loginOutput, HttpServletRequest request, HttpServletResponse response) {
        CookieManager manager = new CookieManager();
        //设置cookie策略，只接受与你对话服务器的cookie，而不接收Internet上其它服务器发送的cookie
        manager.setCookiePolicy(CookiePolicy.ACCEPT_ORIGINAL_SERVER);
        CookieHandler.setDefault(manager);

        String url = scan_login_domain + "/user/scanLogin/login.do?loginName=" + loginOutput.getLoginName();
        logger.info("扫码登录请求连接{}", url);
        String responseStr = WechatUtils.httpRequestNew(url, WechatConstant.POST, null);
        logger.info("扫码登录响应参数{}", responseStr);
        AjaxResult menuResponse = JSONObject.parseObject(responseStr, AjaxResult.class);
        if (menuResponse.isSuccess()) {
            loginOutput.setCode(ScanLoginStatus.SCAN_SUCCESS_LOGIN.getCode());

            String JSESSIONID1 = null;
            List<HttpCookie> listCookie = manager.getCookieStore().getCookies();
            for (HttpCookie httpCookie : listCookie) {
                if ("JSESSIONID".equals(httpCookie.getName())) {
                    JSESSIONID1 = httpCookie.getValue();
                    break;
                }
            }
            logger.info("11111 请求的-----JSESSIONID=" + JSESSIONID1);


            String JSESSIONID2 = CookieUtil.getValue(request, "JSESSIONID");
            logger.info("22222 浏览器的-----JSESSIONID=" + JSESSIONID2);

            if (StringUtils.isNotEmpty(JSESSIONID1) && !JSESSIONID1.equals(JSESSIONID2)) {
                CookieUtil.set(response, "JSESSIONID", JSESSIONID1, "/web", null);
            }

            return menuResponse.getDescription();
        } else {
            throw new BusinessException(menuResponse.getErrorCode(), menuResponse.getDescription());
        }
    }

    /**
     * @param lgToken  登录token
     * @param request
     * @param response
     * @return java.util.Map<java.lang.String, java.lang.Object>
     * @Author yifeng
     * @Description 检查二维码
     * @Date 16:57 2019/2/19
     **/
    public Map<String, Object> checkQRCodeStatus(String lgToken, HttpServletRequest request, HttpServletResponse response) {
        Map<String, Object> resultMap = Maps.newHashMap();

        ScanLoginOutput loginOutput = this.getLoginOutputRedis(lgToken);
        if (null == loginOutput || ScanLoginStatus.QR_INVALID.getCode().equals(loginOutput.getCode())) {
            resultMap.put("code", ScanLoginStatus.QR_INVALID.getCode()); // 已失效
            resultMap.put("message", ScanLoginStatus.getValue(ScanLoginStatus.QR_INVALID.getCode()));
            return resultMap;
        }

        Long currentTime = System.currentTimeMillis();

        Long outTime = 60000 * 5L;
        SysConfig scanOutTime = sysConfigService.findByCode("SCAN_OUT_TIME");
        if (null != scanOutTime) {
            try {
                outTime = 60000 * Long.valueOf(scanOutTime.getValue());
            } catch (NumberFormatException e) {
                logger.error("转换异常", e);
            }
        }
        if (currentTime - loginOutput.getCreateTime() >= outTime) {
            if (ScanLoginStatus.NOT_SCAN.getCode().equals(loginOutput.getCode())
                    || ScanLoginStatus.SCAN_SUCCESS.getCode().equals(loginOutput.getCode())) {
                loginOutput.setCode(ScanLoginStatus.QR_INVALID.getCode()); // 已过期
            }
        }

        // 确认登录，调用接口登录
        if (ScanLoginStatus.SCAN_SUCCESS_CONFIRM.getCode().equals(loginOutput.getCode())) {
            try {
                String forwardUrl = this.scanLogin(loginOutput, request, response);
                loginOutput.setForwardUrl(forwardUrl);
            } catch (Exception e) {
                logger.error("请求登录接口异常", e);
                throw e;
            }
        }

        setLoginOutRedis(loginOutput);

        resultMap.put("code", loginOutput.getCode());
        resultMap.put("message", ScanLoginStatus.getValue(loginOutput.getCode()));
        if (ScanLoginStatus.SCAN_SUCCESS_LOGIN.getCode().equals(loginOutput.getCode())) {
            resultMap.put("forwardUrl", loginOutput.getForwardUrl());
        }
        return resultMap;
    }

    /**
     * 获取登录成功后的跳转路径
     *
     * @param token
     * @param currentUser
     * @param newCurrentUser
     * @return 结果
     * @author yifeng
     * @date 9:32 2019/11/28
     **/
    public AjaxResult getForwardUrl(UsernamePasswordToken token, Subject currentUser, CurrentUser newCurrentUser) {
        AjaxResult ajaxResult = new AjaxResult(true);
        String memberId = newCurrentUser.getId();
        if (sysRoleService.hasRole(memberId, RoleEnum.PARTNER_ROLE.getCode())) {
            // todo 暂时限制 只有行知公社才能登录会员管理系统
//            if (!newCurrentUser.getUsername().equals(XzgsAccountEnum.XZGS.getKey())) {
//                currentUser.getSession().removeAttribute(Constant.CURRENT_USER_KEY);
//                ajaxResult.setSuccess(false);
//                ajaxResult.setErrorCode(100);
//                ajaxResult.setDescription("该账号没有权限登录");
//                return ajaxResult;
//            } else {
//                ajaxResult.setDescription("/member/membermgmt/list.do");
//            }
            ajaxResult.setDescription("/member/membermgmt/list.do");
        } else if (sysRoleService.hasRole(memberId, RoleEnum.XZGS_ADMIN.getCode())) {
            ajaxResult.setDescription("/member/membermgmt/list.do");
        }

        return ajaxResult;
    }
}
